package com.css.bjdt_core.util;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Condition;
import org.nutz.dao.Dao;
import org.nutz.dao.FieldFilter;
import org.nutz.dao.QueryResult;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.Record;
import org.nutz.dao.pager.Pager;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

/**
 * 分页查询工具类.
 */
public class PageQuerys {

	public static final int DEFAULT_PAGE_SIZE = 10;

	public static <T> QueryResult query(Dao dao, Class<T> clazz, Condition cnd, int pageNum, int pageSize) {
		return query(dao, clazz, cnd, true, pageNum, pageSize);
	}

	/**
	 * 分页查询.
	 * 
	 * */
	public static <T> QueryResult query(Dao dao, Class<T> clazz, Condition cnd, boolean autoCount, int pageNum,
			int pageSize) {
		QueryResult result = new QueryResult();
		Pager pager = dao.createPager((pageNum < 1) ? 1 : pageNum, (pageSize < 1) ? DEFAULT_PAGE_SIZE : pageSize);

		List<T> results = dao.query(clazz, cnd, pager);
		result.setList(results);

		if (autoCount) {
			int count = dao.count(clazz, cnd);
			pager.setRecordCount(count);
		}

		result.setPager(pager);
		return result;
	}

	public static QueryResult query(Dao dao, String tableName, Condition cnd, boolean autoCount, int pageNum,
			int pageSize) {
		QueryResult result = new QueryResult();
		Pager pager = dao.createPager((pageNum < 1) ? 1 : pageNum, (pageSize < 1) ? DEFAULT_PAGE_SIZE : pageSize);

		List<Record> results = dao.query(tableName, cnd, pager);
		result.setList(results);

		if (autoCount) {
			int count = dao.count(tableName, cnd);
			pager.setRecordCount(count);
		}

		result.setPager(pager);
		return result;
	}

	/**
	 * ligerUI grid组件分页查询方法
	 * 
	 * @param dao
	 * @param clazz
	 * @param cnd
	 * @param pager
	 * @return
	 */
	public static <T> Map ligerGridQuery(Dao dao, Class<T> clazz, Condition cnd, int pageNum, int pageSize) {
		return ligerGridQuery(dao, clazz, cnd, null, true, pageNum, pageSize);
	}

	/**
	 * ligerUI grid组件分页查询方法
	 * 
	 * @param dao
	 * @param clazz
	 * @param cnd
	 * @param fieldFilter
	 * @param pager
	 * @return
	 */
	public static <T> Map ligerGridQuery(Dao dao, Class<T> clazz, Condition cnd, FieldFilter fieldFilter, int pageNum, int pageSize) {
		return ligerGridQuery(dao, clazz, cnd, fieldFilter, true, pageNum, pageSize);
	}

	/**
	 * ligerUI grid组件分页查询.
	 * 
	 */
	private static <T> Map ligerGridQuery(Dao dao, Class<T> clazz, Condition cnd, FieldFilter fieldFilter,
			boolean autoCount, int pageNum, int pageSize) {
		Dao extDao = dao;
		if (fieldFilter != null) {
			extDao = Daos.ext(extDao, fieldFilter);
		}

		Pager pager = dao.createPager((pageNum < 1) ? 1 : pageNum, (pageSize < 1) ? DEFAULT_PAGE_SIZE : pageSize);
		List<T> results = extDao.query(clazz, cnd, pager);

		Map<String,Object> result = new HashMap<String,Object>();
		result.put("Rows", results);

		if (autoCount) {
			int count = extDao.count(clazz, cnd);
			result.put("Total", count);
		}

		return result;
	}
	
	public static <T> Map ligerGridQuery(BaseDao<T> mapper, Object condition, int pageNum, int pageSize){
		PageHelper.startPage(pageNum, pageSize);
		List<T> results = mapper.selectByExample(condition);
		PageInfo<T> page = new PageInfo<T>(results);
		
		Map<String,Object> result = new HashMap<String,Object>();
		result.put("Rows", results);
		result.put("Total", page.getTotal());
		return result;
	};

	/**
	 * sql分页查询
	 * 
	 * @return
	 */
	public static <T> QueryResult sqlQuery(Dao dao, Class<T> clazz, String sqlStr, Condition cnd, int pageNum,
			int pageSize) {
		return sqlQuery(dao, clazz, sqlStr, cnd, null, null, pageNum, pageSize);
	}

	public static <T> QueryResult sqlQuery(Dao dao, Class<T> clazz, String sqlStr, Condition cnd,
			Map<String, Object> vars, Map<String, Object> params, int pageNum, int pageSize) {
		QueryResult result = new QueryResult();
		Pager pager = dao.createPager((pageNum < 1) ? 1 : pageNum, (pageSize < 1) ? DEFAULT_PAGE_SIZE : pageSize);

		Sql sql = Sqls.create(sqlStr);
		sql.setCallback(Sqls.callback.entities());
		sql.setEntity(dao.getEntity(clazz));
		sql.setCondition(cnd);
		sql.setPager(pager);

		if (vars != null) {
			sql.vars().putAll(vars);
		}
		if (params != null) {
			sql.params().putAll(params);
		}

		dao.execute(sql);

		List<T> results = sql.getList(clazz);
		result.setList(results);

		int count = countSqlResult(dao, sqlStr, cnd, vars, params);
		pager.setRecordCount(count);

		result.setPager(pager);

		return result;
	}

	public static QueryResult sqlQuery(Dao dao, String sqlStr, Condition cnd, Map<String, Object> vars,
			Map<String, Object> params, int pageNum, int pageSize) {
		QueryResult result = new QueryResult();
		Pager pager = dao.createPager((pageNum < 1) ? 1 : pageNum, (pageSize < 1) ? DEFAULT_PAGE_SIZE : pageSize);

		Sql sql = Sqls.create(sqlStr);
		sql.setCallback(Sqls.callback.records());
		sql.setCondition(cnd);
		sql.setPager(pager);

		if (vars != null) {
			sql.vars().putAll(vars);
		}
		if (params != null) {
			sql.params().putAll(params);
		}

		dao.execute(sql);

		List<Record> results = sql.getList(Record.class);
		result.setList(results);

		int count = countSqlResult(dao, sqlStr, cnd, vars, params);
		pager.setRecordCount(count);

		result.setPager(pager);

		return result;
	}

	private static int countSqlResult(Dao dao, String sqlStr, Condition cnd, Map<String, Object> vars,
			Map<String, Object> params) {
		String fromSql = sqlStr;
		// select子句与order by子句会影响count查询,进行简单的排除.
		if (StringUtils.indexOf(fromSql, "FROM") != -1) {
			fromSql = "FROM " + StringUtils.substringAfter(fromSql, "FROM");
		}

		fromSql = StringUtils.substringBefore(fromSql, "ORDER BY");

		String countSqlStr = "SELECT COUNT(*) " + fromSql;

		Sql countSql = Sqls.create(countSqlStr);
		countSql.setCallback(Sqls.callback.integer());
		countSql.setCondition(cnd);

		if (vars != null) {
			countSql.vars().putAll(vars);
		}
		if (params != null) {
			countSql.params().putAll(params);
		}
		dao.execute(countSql);

		return countSql.getInt();
	}
	
	/**
	 * 处理sqlStr 中含有distinct的，获得sqlStr 执行后得到的记录数
	 * @param dao
	 * @param sqlStr
	 * @param vars
	 * @param params
	 * @return
	 */
	public static int countDistinctSql(Dao dao, String sqlStr,  Map<String, Object> vars,
			Map<String, Object> params){
		String fromSql = sqlStr;
		// select子句与order by子句会影响count查询,进行简单的排除.
		fromSql = StringUtils.substringBefore(fromSql, "ORDER BY");
		if (StringUtils.indexOf(fromSql, "FROM") != -1) {
			fromSql = "FROM " + "(" + fromSql+ ")";
		}

		String countSqlStr = "SELECT COUNT(1) " + fromSql;

		Sql countSql = Sqls.create(countSqlStr);
		countSql.setCallback(Sqls.callback.integer());
		

		if (vars != null) {
			countSql.vars().putAll(vars);
		}
		if (params != null) {
			countSql.params().putAll(params);
		}
		dao.execute(countSql);

		return countSql.getInt();
		
	}

}
